/*
 * TripleBuffer.cc
 *
 *  Created on: Apr 2, 2012
 *      Author: s90085
 */

#include "TripleBuffer.h"


TripleBuffer::TripleBuffer( Buffer * ap, Buffer * bp, Buffer * cp) : Monitor( "buffer", 1 ), readp(ap), prevp(bp), fillp(cp) {
	canRead = false;
	firstFill = true;
}

TripleBuffer::~TripleBuffer(){
	delete[] readp;
	delete[] prevp;
	delete[] fillp;
}

Buffer	* TripleBuffer::getReadBuffer(){
    ENTER();
    	if(!canRead){
    		WAIT();
    	}
    	swapBuffer(readp, prevp);
    	canRead = false;
    LEAVE();
    return readp;

}


Buffer	* TripleBuffer::getFillBuffer(){
    ENTER();
    	if (firstFill){
    		firstFill = false;
    		LEAVE();
    		return fillp;
    	}

    	swapBuffer(fillp, prevp);
    	canRead = true;
    	NOTIFY();
    LEAVE();
    return fillp;
}

void TripleBuffer::swapBuffer(Buffer * & bufferOne, Buffer * & bufferTwo){
	Buffer * tmpBuffer = bufferOne;
	bufferOne = bufferTwo;
	bufferTwo = tmpBuffer;
}

Buffer * TripleBuffer::getFirstFillBuffer(){
	return fillp;
}

void TripleBuffer::replaceBuffer(int cameraNumber, Buffer* &newBuffer){
	ENTER();
	bool done = false;

	if (CameraBuffer* tmpBuffer = dynamic_cast<CameraBuffer*>(readp)){
		if (tmpBuffer->getCamera() == cameraNumber){
			swapBuffer(readp, newBuffer);
			done = true;
		}
	}
	if (!done){
		if (CameraBuffer* tmpBuffer = dynamic_cast<CameraBuffer*>(prevp)){
			if (tmpBuffer->getCamera() == cameraNumber){
				swapBuffer(prevp, newBuffer);
				done = true;
			}
		}
	}

	if (!done){
		if (CameraBuffer* tmpBuffer = dynamic_cast<CameraBuffer*>(fillp)){
			if (tmpBuffer->getCamera() == cameraNumber){
				swapBuffer(fillp, newBuffer);
			}
		}
	}
	LEAVE();
}

